package com.fanyue.modules.wzb.utils;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;

import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

public class ChipReadingUtils {

    public static boolean kaiguan = true;

    public enum ConnType {
        Com((byte) 0x01), USB((byte) 0x02), TcpCli((byte) 0x03), TcpSvr((byte) 0x04), UDP((byte) 0x05);
        private final byte Type;

        private ConnType(byte _Type) {
            this.Type = _Type;
        }

        public byte GetConn() {
            return this.Type;
        }
    }

    private static Clibrary DLLProject;

    public static byte[] HexStringToBytes(String HexStr) {
        List<Byte> Bytes = new ArrayList();
        String TmpStr = HexStr.replace(" ", "").replace("-", "").replace(":", "");
        if (TmpStr.length() % 2 > 0) {
            TmpStr = "0" + TmpStr;
        }
        int byteLen = TmpStr.length() / 2;
        byte[] ret = new byte[byteLen];
        for (int i = 0; i < byteLen; i++) {
            int m = i * 2 + 1;
            int n = m + 1;
            int intVal = Integer.decode("0x" + TmpStr.substring(i * 2, i * 2 + 2));
            ret[i] = Byte.valueOf((byte) intVal);
        }
        return ret;
    }

    public static void setKaiguan(boolean var) {
         kaiguan = var;
    }

    public static String code() {
        DLLProject = Clibrary.instance;
        final boolean[] isExit = {false};
        final String[] content = {null};
        Clibrary.CallReceive callReceive = new Clibrary.CallReceive() {

            @Override
            public int MessageHandle(byte Type, byte Command, int RecSize, ByteByReference buf) {
                byte[] b = buf.getPointer().getByteArray(0, RecSize);
                String TmpStr = BytesToHexString(b, "");
//                System.out.println(TmpStr);
                content[0] = TmpStr;
                return 0;
            }
        };

        Integer RetDword = 0;
        RetDword = DLLProject.Connect(ChipReadingUtils.ConnType.USB.GetConn(), null, callReceive);

        String status = "Status:" + (RetDword == 0 ? "Succeed" : "Failure[" + Integer.toHexString(RetDword) + "]") + "\r\n";
        System.out.println(status);
//        RetDword = DLLProject.ReadSingle();
        int i = 1;
        while (!isExit[0] && i <= 15 && kaiguan){
            RetDword = DLLProject.ReadSingle();
//            System.out.println(RetDword);
            if(RetDword != 0){
                System.out.println("第"+i+"次未能获取到内容");
                isExit[0] = false;

                try {
                    Thread.sleep(1000); // 使当前线程休眠1000毫秒（1秒）
                    System.out.println("开启下一次循环");
                    i++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("已获取到内容，不再循环");
                isExit[0] = true;
            }

        }
        if(RetDword == 0){
            System.out.println("获取到内容："+content[0]);
        } else {
            System.out.println("未能获取到内容，页面重新调取该页面");
        }
        return content[0];
    }

    public interface Clibrary extends Library {

        // DLL文件默认路径为项目根目录，若DLL文件存放在项目外，请使用绝对路径。（此处：(Platform.isWindows()?"msvcrt":"c")指本地动态库msvcrt.dll）
//    Clibrary instance = (Clibrary) Native.load("D:\\Java\\RFID_EPC_Project\\DLLProject.dll", Clibrary.class);
        //ChipReadingUtils.Clibrary instance = (ChipReadingUtils.Clibrary) Native.load("D:\\workspace\\fanyue\\storehouse-wzb\\DLLProject_x64.dll", ChipReadingUtils.Clibrary.class);
        ChipReadingUtils.Clibrary instance = (ChipReadingUtils.Clibrary) Native.load("/data/data/service/api/DLLProject_x64.dll", ChipReadingUtils.Clibrary.class);

        public interface CallReceive extends StdCallLibrary.StdCallCallback {

            int MessageHandle(byte Type, byte Command, int RecSize, ByteByReference buf);
        }

        public interface SvrCallReceive extends StdCallLibrary.StdCallCallback {

            int MessageHandle(byte Type, String IP, int Port, int LpRecSize, ByteByReference LpRecByt);
        }

        // 声明将要调用的DLL中的方法,可以是多个方法(此处示例调用本地动态库msvcrt.dll中的printf()方法)
        int Connect(byte ConnType, String ConnChar, ChipReadingUtils.Clibrary.CallReceive rc);

        int Disconnect();

        int SetRegion(byte Region);

        int GetRfChannel(ByteByReference RfChannel);

        int SetRfChannel(byte RfChannel);

        int SetFhss(boolean Fhss);

        int SetPower(int Power);

        int GetPower(IntByReference Power);

        int ReadSingle();

        int SetCW(boolean CW);

        int ReadMulti(int PollCount);

        int StopRead();

        int GetModuleInfo(ByteByReference InfoType, PointerByReference InfoData, IntByReference DataSize);

        int SetSelectMode(byte Mode);

        int SetSelectParam(byte Target, byte Action, byte MemBank, int Pointer, byte Truncated, byte[] MaskData, byte MaskSize);

        int ImpinjMonzaQT(byte[] AccessPassword, byte RW, byte Persistence, byte Payload, byte[] PC, byte[] EPC, byte[] QTControl);

        int NxpChangeConfig(byte[] AccessPassword, byte[] Config, byte[] PC, byte[] EPC);

        int NxpChangeEas(byte[] AccessPassword, byte Protect, byte[] PC, byte[] EPC);

        int NxpReadProtect(byte[] AccessPassword, byte Protect, byte[] PC, byte[] EPC);

        int NxpEasAlarm(byte[] EASAlarmCode);

        int GetQuery(ByteByReference DR, ByteByReference M, ByteByReference TRext, ByteByReference Sel, ByteByReference Session, ByteByReference Target, ByteByReference Q);

        int SetQuery(byte DR, byte M, byte TRext, byte Sel, byte Session, byte Target, byte Q);

        int ReadData(byte[] AccessPassword, byte MemBank, int StartIndex, int Length, byte[] PC, byte[] EPC, byte[] Data, IntByReference Size);

        int WriteData(byte[] AccessPassword, byte MemBank, int StartIndex, byte[] Data, int Size, byte[] PC, byte[] EPC);

        int LockUnlock(byte[] AccessPassword, byte[] LD, byte[] PC, byte[] EPC);

        int Kill(byte[] AccessPassword, byte[] PC, byte[] EPC);

        int ScanJammer(ByteByReference CH_L, ByteByReference CH_H, byte[] JMR);

        int ScanRSSI(ByteByReference CH_L, ByteByReference CH_H, byte[] JMR);

        int SetModemPara(byte Mixer_G, byte IF_G, int Thrd);

        int GetModemPara(ByteByReference Mixer_G, ByteByReference IF_G, IntByReference Thrd);

        int NetCfg_Open(String IP);

        int NetCfg_Close();

        int NetCfg_SearchForDevices(byte DeviceType, IntByReference Count, byte[] Data, IntByReference Length);

        int NetCfg_FactoryReset(byte DeviceType, byte[] MAC);

        int NetCfg_GetInfo(byte DeviceType, byte[] MAC, byte[] Data, IntByReference Length);

        int NetCfg_SetInfo(byte DeviceType, byte[] LocalMAC, byte[] DevMAC, byte[] Data, int Length);

        int Svr_Startup(byte ConnType, String ConnChar, ChipReadingUtils.Clibrary.SvrCallReceive rc);

        int Svr_CleanUp();

        int Svr_Send(String ConnChar, byte[] Data, int Length);
    }
    public class CallReceiveImpl implements ChipReadingUtils.Clibrary.CallReceive {

        @Override
        public int MessageHandle(byte Type, byte Command, int RecSize, ByteByReference buf) {
            // TODO Auto-generated method stub
            byte[] b = buf.getPointer().getByteArray(0, RecSize);
            System.out.println(b);
            System.out.println(Base64.getEncoder().encodeToString(b));
            String TmpStr = BytesToHexString(b, "");
//            ShowRetDword("DataReceive", TmpStr);
//            ProcReceive(Type, Command, b);
            System.out.println(TmpStr);
            return 0;
        }
    }
    public static String BytesToHexString(byte[] b, String Padding) {
        return BytesToHexString(b, Padding, 0, b.length);
    }
    public static String BytesToHexString(byte[] b, String Padding, int startIndex, int length) {
        String RetStr = "";
        for (int i = 3; i < length-2; i++) {
            String TmpStr = Integer.toHexString(b[i + startIndex] & 0xFF);
            if (TmpStr.length() < 2) {
                TmpStr = "0" + TmpStr;
            }
            RetStr += TmpStr + Padding;
        }
        if (RetStr.length() > 0) {
            RetStr = RetStr.substring(0, RetStr.length() - Padding.length()).toUpperCase();
        }
        return RetStr;
    }
}

